﻿using DocumentFormat.OpenXml;

using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
using System;
using System.Collections.Generic;
using System.Drawing.Printing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace XmlCall
{
    /// <summary>
    /// 页脚和页眉
    /// </summary>
    public static class XmlHeaderFooter
    {
        public static void AppendHeader(MainDocumentPart mainDocPart, string newHeaderText,PageSize pageSize)
        {
            string retionId_header1 = "r002";
            string retionId_header2 = "r003";
            string retionId_header3 = "r004";

            string retionId_foot1 = "r005";
            string retionId_foot2 = "r006";
            string retionId_foot3 = "r007";

            #region 页眉                
            //Header header1 = new Header(new Paragraph(new Run(new Text() { Text = "header1" })));
            //Header header2 = new Header(new Paragraph(new Run(new Text() { Text = "header2" })));
            //Header header3 = new Header(new Paragraph(new Run(new Text() { Text = "header3" })));
            Header header1 = GeneratePageHeaderPart("header1");
            Header header2 = GeneratePageHeaderPart("header2");
            Header header3 = GeneratePageHeaderPart("header3");

            HeaderPart headerPart1 = mainDocPart.AddNewPart<HeaderPart>();
            retionId_header1 = mainDocPart.GetIdOfPart(headerPart1);
            headerPart1.Header = header1;

            HeaderPart headerPart2 = mainDocPart.AddNewPart<HeaderPart>();
            retionId_header2 = mainDocPart.GetIdOfPart(headerPart2);
            headerPart2.Header = header2;

            HeaderPart headerPart3 = mainDocPart.AddNewPart<HeaderPart>();
            retionId_header3 = mainDocPart.GetIdOfPart(headerPart3);
            headerPart3.Header = header3;

            // mainDocPart.AddNewPart<HeaderPart>("application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml", retion_header1).Header = header1;
            //mainDocPart.AddNewPart<HeaderPart>("application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml", retion_header2).Header = header2;
            // mainDocPart.AddNewPart<HeaderPart>("application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml", retion_header3).Header = header3;
            #endregion

            #region 页脚                
            //Footer footer1 = new Footer(new Paragraph(new Run(new Text() { Text = "footer1" }))); 
            //Footer footer2 = new Footer(new Paragraph(new Run(new Text() { Text = "footer2" }))); 
            //Footer footer3 = new Footer(new Paragraph(new Run(new Text() { Text = "footer3" })));

            Footer footer1 = GeneratePageFooterPart("footer1");
            Footer footer2 = GeneratePageFooterPart("footer2");
            Footer footer3 = GeneratePageFooterPart("footer3");


            FooterPart footerPart1 = mainDocPart.AddNewPart<FooterPart>();
            footerPart1.Footer = footer1;
            retionId_foot1 = mainDocPart.GetIdOfPart(footerPart1);

            FooterPart footerPart2 = mainDocPart.AddNewPart<FooterPart>();
            footerPart2.Footer = footer2;
            retionId_foot2 = mainDocPart.GetIdOfPart(footerPart2);

            FooterPart footerPart3 = mainDocPart.AddNewPart<FooterPart>();
            footerPart3.Footer = footer3;
            retionId_foot3 = mainDocPart.GetIdOfPart(footerPart3);

            //mainDocPart.AddNewPart<FooterPart>("application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml", retion_foot1).Footer = footer1;
            // mainDocPart.AddNewPart<FooterPart>("application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml", retion_foot2).Footer = footer2;
            // mainDocPart.AddNewPart<FooterPart>("application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml", retion_foot3).Footer = footer3;               
            #endregion

            var secPrs = mainDocPart.Document.Descendants<SectionProperties>();
            #region 追加页眉页脚
            foreach (var item in secPrs)
            {
                item.Append(new HeaderReference() { Id = retionId_header1, Type = HeaderFooterValues.First });
                item.Append(new HeaderReference() { Id = retionId_header2, Type = HeaderFooterValues.Even });
                item.Append(new HeaderReference() { Id = retionId_header3, Type = HeaderFooterValues.Default });
                item.Append(new FooterReference() { Id = retionId_foot1, Type = HeaderFooterValues.First });
                item.Append(new FooterReference() { Id = retionId_foot2, Type = HeaderFooterValues.Even });
                item.Append(new FooterReference() { Id = retionId_foot3, Type = HeaderFooterValues.Default });
            }
            #endregion
            if (secPrs.Count() == 0)
            {
                /*设置 页眉，页脚和页面关系*/
                SectionProperties sectPr = new SectionProperties(
                new HeaderReference() { Id = retionId_header1, Type = HeaderFooterValues.First },
                new HeaderReference() { Id = retionId_header2, Type = HeaderFooterValues.Even },
                new HeaderReference() { Id = retionId_header3, Type = HeaderFooterValues.Default },
                new FooterReference() { Id = retionId_foot1, Type = HeaderFooterValues.First },
                new FooterReference() { Id = retionId_foot2, Type = HeaderFooterValues.Even },
                new FooterReference() { Id = retionId_foot3, Type = HeaderFooterValues.Default }
                );
                sectPr.Append(pageSize);
                mainDocPart.Document.Body.AppendChild<SectionProperties>(sectPr);
            }
        }


        /// <summary>
        /// 【要显示页眉和页脚 要在Body中sectPr节点 PageSize参数】
        /// </summary>
        /// <param name="doc"></param>
        /// <param name="newHeaderText">页眉文字</param>
        public static HeaderPart AddHeader(MainDocumentPart mainDocPart, string newHeaderText)
        {

            HeaderPart newHeaderPart = mainDocPart.AddNewPart<HeaderPart>();
            string rId = mainDocPart.GetIdOfPart(newHeaderPart);

            GeneratePageHeaderPart(newHeaderText).Save(newHeaderPart);

            foreach (SectionProperties sectProperties in
              mainDocPart.Document.Descendants<SectionProperties>())
            {

                HeaderReference newHeaderReference =
                  new HeaderReference() { Id = rId, Type = HeaderFooterValues.Default };
                sectProperties.Append(newHeaderReference);
            }
            mainDocPart.Document.Save();
            return newHeaderPart;

        }
        // Creates an header instance and adds its children.
        private static Header GeneratePageHeaderPart(string HeaderText)
        {
            // set the position to be the center
            PositionalTab pTab = new PositionalTab()
            {
                Alignment = AbsolutePositionTabAlignmentValues.Right,
                RelativeTo = AbsolutePositionTabPositioningBaseValues.Margin,
                Leader = AbsolutePositionTabLeaderCharValues.None
            };

            RunProperties runProperties = new RunProperties();
            runProperties.RunFonts = new RunFonts() { Hint = FontTypeHintValues.EastAsia };
            runProperties.Languages = new Languages() { Val = "en-US", EastAsia = "zh-CN" };

            var element =
              new Header(
                new Paragraph(
                  new ParagraphProperties(
                    new ParagraphStyleId() { Val = "3" }),
                  new Run(runProperties,
                    new Text(HeaderText))
                )
              );

            return element;
        }
        /// <summary>
        /// 【要显示页眉和页脚 要在Body中sectPr节点 PageSize参数】
        /// </summary>
        /// <param name="mainDocPart"></param>
        /// <param name="newFooterText"></param>
        /// <param name="pageSize"></param>
        public static FooterPart AddFooter(MainDocumentPart mainDocPart, string newFooterText)
        {


 
            mainDocPart.DeleteParts(mainDocPart.FooterParts);


            FooterPart newFooterPart = mainDocPart.AddNewPart<FooterPart>();
            string rId = mainDocPart.GetIdOfPart(newFooterPart);


            GeneratePageFooterPart(newFooterText).Save(newFooterPart);

            foreach (SectionProperties sectProperties in
              mainDocPart.Document.Descendants<SectionProperties>())
            {

                FooterReference newFooterReference =
                  new FooterReference() { Id = rId, Type = HeaderFooterValues.Default };


                //// 添加页码
                //Paragraph paragraph = new Paragraph(new Run(new Text("第")));
                //paragraph.Append(new FieldChar());
                //paragraph.Append(new Run(new FieldCode("PAGE")));
                //paragraph.Append(new Run(new Text("页")));

                //newFooterReference.Append(paragraph);

                sectProperties.Append(newFooterReference);

            }


            mainDocPart.Document.Save();
            return newFooterPart;
        }

        private static Footer GeneratePageFooterPart(string FooterText)
        {
            PositionalTab pTab = new PositionalTab()
            {
                Alignment = AbsolutePositionTabAlignmentValues.Right,
                RelativeTo = AbsolutePositionTabPositioningBaseValues.Margin,
                Leader = AbsolutePositionTabLeaderCharValues.None
            };

            var elment =
                new Footer(
                    new Paragraph(
                        new ParagraphProperties(
                            new ParagraphStyleId() { Val = "Footer" }),
                        new Run(pTab,
                            new Text(FooterText))
                                )
                            );
            return elment;
        }



        public static string GetFootText(MainDocumentPart mainDocumentPart)
        {
            var footerParts = mainDocumentPart.GetPartsOfType<FooterPart>();
            if (footerParts == null)
            {
                return string.Empty;
            }
            string footText = string.Empty;
            // 找到页脚
            FooterPart footerPart = footerParts.FirstOrDefault();
            if (footerPart != null)
            {
                var footer = footerPart.Footer;

                //var textList = footer.Descendants<Text>().ToList();
                //var textValueList = textList.Select(x => x.InnerText);
                //footText = string.Join("", textValueList);

                footText = GetTextFromFooter(footer);
            }
            return footText;

        }
        private static string GetTextFromFooter(Footer footer)
        {
            var text = from paragraph in footer.Elements<Paragraph>()
                       from run in paragraph.Elements<Run>()
                       from ddddd in run.Elements<Text>()
                       select ddddd.Text;

            return string.Join("", text);
        }
        private static string GetTextFromHeader(Header header)
        {
            var text = from paragraph in header.Elements<Paragraph>()
                       from run in paragraph.Elements<Run>()
                       from ddddd in run.Elements<Text>()
                       select ddddd.Text;

            return string.Join("", text);
        }
        public static string GetHeadText(MainDocumentPart mainDocumentPart)
        {
            var headerParts = mainDocumentPart.GetPartsOfType<HeaderPart>();
            if (headerParts == null)
            {
                return string.Empty;
            }
            string heradText = string.Empty;
            // 找到页脚
            HeaderPart headPart = headerParts.FirstOrDefault();
            if (headPart != null)
            {
                var herader = headPart.Header;

                //var textList = herader.Descendants<Text>().ToList();
                //var textValueList = textList.Select(x => x.InnerText);
                //heradText = string.Join("", textValueList);
                heradText = GetTextFromHeader(herader);
            }
            return heradText;

        }
        /// <summary>
        /// 修改页眉
        /// </summary>
        /// <param name="mainDocumentPart"></param>
        /// <param name="newHeadText"></param>
        public static void ModifyHeaderText(MainDocumentPart mainDocumentPart, string oldHeadText, string newHeadText)
        {


            #region 这种方式也可以，只是会修改页眉文本以外的值，作为后面的考虑方式
            // 修改页眉
            var headers = mainDocumentPart.HeaderParts;
            if (headers != null)
            {
                foreach (var header in headers)
                {
                    if (header.Header != null)
                    {
                        var paras = header.Header.Descendants<DocumentFormat.OpenXml.Wordprocessing.Paragraph>();
                        foreach (var para in paras)
                        {
                            var runs = para.Descendants<DocumentFormat.OpenXml.Wordprocessing.Text>();
                            foreach (var run in runs)
                            {
                                string tempText = run.Text;
                                tempText = tempText.Replace(oldHeadText, newHeadText);
                                run.Text = tempText;
                            }
                        }
                    }
                    //if (header.RootElement != null)
                    //{
                    //    var paras = header.RootElement.Descendants<DocumentFormat.OpenXml.Wordprocessing.Paragraph>();
                    //    foreach (var para in paras)
                    //    {
                    //        var runs = para.Descendants<DocumentFormat.OpenXml.Wordprocessing.Text>();
                    //        foreach (var run in runs)
                    //        {
                    //            run.Text = newHeadText;
                    //        }
                    //    }
                    //}
                }
            }
            #endregion


        }
        /// <summary>
        /// 修改页脚
        /// </summary>
        /// <param name="mainDocumentPart"></param>
        /// <param name="newFooterText"></param>
        public static void ModifyFooterText(MainDocumentPart mainDocumentPart, string oldFooterText, string newFooterText)
        {


            var footers = mainDocumentPart.FooterParts;
            if (footers != null)
            {
                foreach (var footer in footers)
                {
                    if (footer.Footer != null)
                    {
                        var paras = footer.Footer.Descendants<DocumentFormat.OpenXml.Wordprocessing.Paragraph>();


                        foreach (var para in paras)
                        {
                            var runs = para.Descendants<DocumentFormat.OpenXml.Wordprocessing.Text>();
                            foreach (var run in runs)
                            {

                                string tempText = run.Text;
                                tempText = tempText.Replace(oldFooterText, newFooterText);
                                run.Text = tempText;


                            }
                        }
                    }
                    //if (footer.RootElement != null)
                    //{
                    //    var paras = footer.RootElement.Descendants<DocumentFormat.OpenXml.Wordprocessing.Paragraph>();
                    //    foreach (var para in paras)
                    //    {

                    //        var runs = para.Descendants<DocumentFormat.OpenXml.Wordprocessing.Text>();
                    //        foreach (var run in runs)
                    //        {
                    //            run.Text = newFooterText;
                    //        }
                    //    }
                    //}
                }
            }


        }

        /// <summary>
        /// 获取所有节点的 页眉和页脚
        /// </summary>
        /// <returns></returns>
        //public static Dictionary<string, string> GetSectionHeaderFooter(MainDocumentPart mainDocumentPart)
        //{
        //    var headerParts = mainDocumentPart.HeaderParts.ToList();
        //    //遍历所有节点
        //    foreach (var section in mainDocumentPart.Document.Body.Elements<SectionProperties>().Select((s, i) => new { Section = s, Index = i }))
        //    {
        //        // 为每个节添加或修改页眉  
        //        HeaderPart headerPart = null;
        //        if (headerParts.Count > section.Index)
        //        {
        //            headerPart = headerParts[section.Index];
        //        }
        //        else
        //        {
        //            headerPart = headerParts.AddNewPart<HeaderPart>();
        //        }


        //    }

        //}

    }
}
